package tfts

import "sort"

type Source int

var results []result0
var deferredRun = false

const (
	AttackS Source = iota
	CastS
	PassiveS
	HealS
	ShieldS // 注意技能护盾不参与挨打回蓝
	GrowS
)

type result0 struct {
	dps    int
	output string
}

// 用于辅助技能计算的record
type castRecord struct {
	critical  int // 施法前暴击次数
	attacks0  int // 施法前攻击次数
	totalMana int // 累计回蓝
}

type record0 struct {
	ticks        int // 当前事件，单位ms
	Now          int // 当前的时间，单位秒
	AtkTimes     int // 攻击次数
	CastTimes    int // 施法次数
	TotalDmg     int // 总伤害
	DPS          int
	RegenTimes   int     // 每半秒回蓝次数
	TotalManaReg float64 // 自动蓝量回复的总量
	SecRecord    []int   // 记录每一秒的伤害
	AtkRecord    []int   // 记录每一次攻击的伤害
	CastRecord   []int   // 记录每一次施法的伤害
	ActRecord    []int   // 记录被动伤害
	SelfMitigate int     // 记录总自我缓和伤害
	Sustain      int     // 记录护盾+治疗,已乘入缓和系数
	PureTaken    int     // 记录不施法时自带生命值的自我缓和伤害
	SpendMana    int     // 总共消耗的法力值
	BeatenMana   float64 // 挨打回蓝
}

func DeferredOutput() {
	outputLevel = METRIC
	deferredRun = true
}

func AllOut() {
	sort.Slice(results, func(i, j int) bool {
		return results[i].dps > results[j].dps
	})
	for _, res := range results {
		print(res.output)
	}
}

func (c *castRecord) reset() {
	c.critical = 0
	c.attacks0 = 0
}

func (r *record0) record(dmg float64, source Source) {
	for len(r.SecRecord) < r.Now+1 {
		r.SecRecord = append(r.SecRecord, 0)
	}
	r.SecRecord[r.Now] += int(dmg)
	switch source {
	case AttackS:
		for len(r.AtkRecord) < r.AtkTimes {
			r.AtkRecord = append(r.AtkRecord, 0)
		}
		r.AtkRecord[r.AtkTimes-1] += int(dmg)
	case CastS:
		// record前castTimes已加1
		for len(r.CastRecord) < r.CastTimes {
			r.CastRecord = append(r.CastRecord, 0)
		}
		r.CastRecord[r.CastTimes-1] += int(dmg)
	case PassiveS:
		r.ActRecord = append(r.ActRecord, int(dmg))
	default:
		panic("unknown damage source")
	}
}

func (r *record0) AvgCastDmg() int {
	if len(r.CastRecord) == 0 {
		return 0
	}
	return r.AllCastDmg() / len(r.CastRecord)
}

func (r *record0) AllCastDmg() int {
	sum := 0
	for _, dmg := range r.CastRecord {
		sum += dmg
	}
	return sum
}

func (r *record0) AvgAtkDmg() int {
	if len(r.AtkRecord) == 0 {
		return 0
	}
	return r.AllAtkDmg() / len(r.AtkRecord)
}

func (r *record0) AllAtkDmg() int {
	sum := 0
	for _, dmg := range r.AtkRecord {
		sum += dmg
	}
	return sum
}

func (r *record0) AllPassiveDmg() int {
	sum := 0
	for _, dmg := range r.ActRecord {
		sum += dmg
	}
	return sum
}
